home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / faxd / FaxModem.h < prev    next >
C/C++ Source or Header  |  1994-08-01  |  16KB  |  413 lines

  1. /*    $Header: /usr/people/sam/fax/faxd/RCS/FaxModem.h,v 1.79 1994/04/08 03:49:33 sam Rel $ */
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #ifndef _FAXMODEM_
  26. #define    _FAXMODEM_
  27. /*
  28.  * Fax Modem Driver Interface.
  29.  */
  30. #include <stdarg.h>
  31. #include "Class2Params.h"
  32. #include "tiffio.h"
  33.  
  34. class FaxServer;
  35. class FaxMachineInfo;
  36. class ModemConfig;
  37.  
  38. // NB: these would be enums in the FaxModem class
  39. //     if there were a portable way to refer to them!
  40. typedef unsigned int CallStatus;    // return status from dialing op
  41. typedef    unsigned int CallType;        // type detected for incoming call
  42. typedef    unsigned int AnswerType;    // type of call to answer for
  43. typedef unsigned int SpeakerVolume;
  44. typedef    unsigned int ATResponse;    // response code from AT command
  45. typedef    unsigned int BaudRate;        // serial line communication rate
  46. typedef    unsigned int FlowControl;    // serial line flow control scheme
  47. typedef    unsigned int SetAction;        // how to act when setting line
  48. typedef struct {
  49.     const char*    msg;        // string to match
  50.     u_short    len;        // string length
  51.     ATResponse    expect;        // next AT response to expect
  52.     CallStatus    status;        // resultant call status
  53.     CallType    type;        // resultant call type
  54. } AnswerMsg;
  55.  
  56. /*
  57.  * AT command escape codes.  Command strings specified in the
  58.  * modem configuration file are parsed and embedded commands
  59.  * are converted to one of the escape codes below.
  60.  */ 
  61. #define    ord(e)    ((int)(e))
  62.  
  63. #define    ESC_BR300    (0x80|ord(FaxModem::BR300))    // 300 bps
  64. #define    ESC_BR1200    (0x80|ord(FaxModem::BR1200))    // 1200 bps
  65. #define    ESC_BR2400    (0x80|ord(FaxModem::BR2400))    // 2400 bps
  66. #define    ESC_BR4800    (0x80|ord(FaxModem::BR4800))    // 4800 bps
  67. #define    ESC_BR9600    (0x80|ord(FaxModem::BR9600))    // 9600 bps
  68. #define    ESC_BR19200    (0x80|ord(FaxModem::BR19200))    // 19200 bps
  69. #define    ESC_BR38400    (0x80|ord(FaxModem::BR38400))    // 38400 bps
  70. #define    ESC_BR57600    (0x80|ord(FaxModem::BR57600))    // 57600 bps
  71. #define    ESC_BR76800    (0x80|ord(FaxModem::BR76800))    // 76800 bps
  72. #define    ESC_XON        (0x80|0xf)            // XON/XOFF flow control
  73. #define    ESC_RTS        (0x80|0xe)            // RTS/CTS flow control
  74.  
  75. /*
  76.  * This is an abstract class that defines the interface to
  77.  * the set of modem drivers.  Real drivers are derived from
  78.  * this and fill in the pure virtual methods to, for example,
  79.  * send specific commands to the modem.  The Class2Params
  80.  * structure defines the session parameters used/supported
  81.  * by this interface.  Class2Params is derived from the
  82.  * set of parameters supported by the Class 2 interface spec.
  83.  */
  84. class FaxModem {
  85. public:
  86.     static FaxModem* deduceModem(FaxServer&, const ModemConfig& config);
  87.  
  88.     enum {            // FaxModemCallStatus
  89.     OK       = 0,        // phone answered & carrier received
  90.     BUSY       = 1,        // destination phone busy
  91.     NOCARRIER  = 2,        // no carrier from remote
  92.     NOANSWER   = 3,        // no answer from remote
  93.     NODIALTONE = 4,        // no local dialtone (phone not plugged in?)
  94.     ERROR       = 5,        // error in dial command
  95.     FAILURE       = 6,        // other problem (e.g. modem turned off)
  96.     };
  97.     static const char* callStatus[7];
  98.  
  99.     enum {            // FaxModemCallType
  100.     CALLTYPE_ERROR    = 0,    // error deducing type of incoming call
  101.     CALLTYPE_DATA    = 1,    // data connection
  102.     CALLTYPE_FAX    = 2,    // fax connection
  103.     CALLTYPE_VOICE    = 3,    // voice connection
  104.     CALLTYPE_UNKNOWN = 4,    // unknown variety
  105.     };
  106.  
  107.     enum {            // FaxModemSpeakerVolume
  108.     OFF    = 0,        // nothing
  109.     QUIET    = 1,        // somewhere near a dull chirp
  110.     LOW    = 2,        // normally acceptable
  111.     MEDIUM    = 3,        // heard above a stereo
  112.     HIGH    = 4,        // ear splitting
  113.     };
  114.  
  115.     enum {            // DTE-DCE communication rate
  116.     BR0    = 0,        // force hangup/drop DTR
  117.     BR300    = 1,        // 300 bits/sec
  118.     BR1200    = 2,        // 1200 bits/sec
  119.     BR2400    = 3,        // 2400 bits/sec
  120.     BR4800    = 4,        // 4800 bits/sec
  121.     BR9600    = 5,        // 9600 bits/sec
  122.     BR19200    = 6,        // 19200 bits/sec
  123.     BR38400    = 7,        // 38400 bits/sec
  124.     BR57600    = 8,        // 57600 bits/sec
  125.     BR76800    = 9,        // 76800 bits/sec
  126.     };
  127.  
  128.     enum {
  129.     FLOW_NONE    = 0,    // no flow control
  130.     FLOW_CURRENT    = 1,    // whatever current setting is
  131.     FLOW_XONXOFF    = 2,    // XON/XOFF software flow control
  132.     FLOW_RTSCTS    = 3    // RTS/CTS hardware flow control
  133.     };
  134.  
  135.     enum {
  136.     ACT_NOW        = 0,    // set terminal parameters now
  137.     ACT_DRAIN    = 1,    // set parameters after draining output queue
  138.     ACT_FLUSH    = 2,    // set parameters after flush both queues
  139.     };
  140.  
  141.     enum {            // FaxModemAnswerType
  142.     ANSTYPE_ANY    = 0,    // any kind of call
  143.     ANSTYPE_DATA    = 1,    // data call
  144.     ANSTYPE_FAX    = 2,    // fax call
  145.     ANSTYPE_VOICE    = 3,    // voice call
  146.     };
  147.  
  148.     enum {            // ATResponse
  149.     AT_NOTHING    = 0,    // for passing as a parameter
  150.     AT_OK        = 1,    // "OK" response
  151.     AT_CONNECT    = 2,    // "CONNECT" response
  152.     AT_NOANSWER    = 3,    // "NO ANSWER" response
  153.     AT_NOCARRIER    = 4,    // "NO CARRIER" response
  154.     AT_NODIALTONE    = 5,    // "NO DIALTONE" response
  155.     AT_BUSY        = 6,    // "BUSY" response
  156.     AT_OFFHOOK    = 7,    // "PHONE OFF-HOOK" response
  157.     AT_RING        = 8,    // "RING" response
  158.     AT_ERROR    = 9,    // "ERROR" response
  159.     AT_EMPTYLINE    = 10,    // empty line (0 characters received)
  160.     AT_TIMEOUT    = 11,    // timeout waiting for response
  161.     AT_OTHER    = 12,    // unknown response (not one of above)
  162.     };
  163. private:
  164.     FaxServer&    server;        // server for getting to device
  165.     fxStr    resetCmds;    // commands to use for reset operation
  166.     long    dataTimeout;    // baud rate-dependent data timeout
  167.     BaudRate    rate;        // selected DTE-DCE communication rate
  168.     FlowControl    iFlow;        // input flow control scheme
  169.     FlowControl    oFlow;        // output flow control scheme
  170.     u_char    RTCbuf[40];    // buffer for RTC parsing on receive
  171.     u_long    recvWord;    // for counting EOLs on receive
  172.     u_long    recvEOLCount;    // EOL count for received page
  173.     u_long    savedWriteOff;    // file offset to start of page data
  174. protected:
  175. // NB: these are defined protected for convenience (XXX)
  176.     const ModemConfig& conf;    // configuration parameters
  177.     FlowControl    flowControl;    // current DTE-DCE flow control scheme
  178.     u_int    modemServices;    // services modem supports
  179.     fxStr    modemMfr;    // manufacturer identification
  180.     fxStr    modemModel;    // model identification
  181.     fxStr    modemRevision;    // product revision identification
  182.     Class2Params modemParams;    // NOTE: these are masks of Class 2 codes
  183.     char    rbuf[1024];    // last input line
  184.     ATResponse    lastResponse;    // last atResponse code
  185.     fxStr    mfrQueryCmd;    // manufacturer identification command
  186.     fxStr    modelQueryCmd;    // model identification command
  187.     fxStr    revQueryCmd;    // product revision identification command
  188.  
  189.     static const char* serviceNames[9];    // class 2 services
  190.     static const u_char digitMap[12*2+1];// Table 3/T.30 digit encoding table
  191.  
  192.     FaxModem(FaxServer&, const ModemConfig&);
  193.  
  194. // setup and configuration
  195.     virtual fxBool selectBaudRate(BaudRate max, FlowControl i, FlowControl o);
  196.     virtual fxBool setupModem() = 0;
  197.     virtual fxBool setupManufacturer(fxStr& mfr);
  198.     virtual fxBool setupModel(fxStr& model);
  199.     virtual fxBool setupRevision(fxStr& rev);
  200.  
  201.     fxBool doQuery(fxStr& queryCmd, fxStr& result, long ms = 30*1000);
  202. // dial/answer interactions with derived classes
  203.     virtual const AnswerMsg* findAnswer(const char* s);
  204.     virtual CallType answerResponse(fxStr& emsg);
  205.     virtual CallStatus dialResponse() = 0;
  206. // data transfer timeout controls
  207.     void    setDataTimeout(long secs, u_int br);
  208.     long    getDataTimeout() const;
  209. // miscellaneous
  210.     void    pause(u_int ms);
  211.     void    countPage();
  212.     void    modemTrace(const char* fmt, ...);
  213.     void    modemSupports(const char* fmt, ...);
  214.     void    modemCapability(const char* fmt, ...);
  215.     void    protoTrace(const char* fmt, ...);
  216.     void    serverTrace(const char* fmt, ...);
  217.     void    traceBits(u_int bits, const char* bitNames[]);
  218.     void    traceModemParams();
  219.     void    tracePPR(const char* dir, u_int ppr);
  220.     void    tracePPM(const char* dir, u_int ppm);
  221.  
  222.     static fxBool EOLcode(u_long& w);
  223.  
  224.     void    startPageRecv();
  225.     void    recvPageData(TIFF* tif, u_char* bp, int n);
  226.     void    endPageRecv(const Class2Params&);
  227.     u_long    getRecvEOLCount() const;
  228. // modem i/o support
  229.     void    trimModemLine(char buf[], int& cc);
  230.     int        getModemLine(char buf[], u_int bufSize, long ms = 0);
  231. // support to write to modem w/ timeout
  232.     void    beginTimedTransfer();
  233.     void    endTimedTransfer();
  234.     fxBool    wasTimeout();
  235.     void    setTimeout(fxBool);
  236.     void    flushModemInput();
  237.     fxBool    putModem(void* data, int n, long ms = 0);
  238.     fxBool    putModemData(void* data, int n);
  239.     fxBool    putModemDLEData(const u_char* data, u_int,
  240.             const u_char* brev, long ms);
  241.     fxBool    putModemLine(const char* cp);
  242.     int        getModemChar(long ms = 0);
  243.     int        getModemDataChar();
  244.     void    startTimeout(long ms);
  245.     void    stopTimeout(const char* whichdir);
  246. // host-modem protocol parsing support
  247.     static const char* ATresponses[13];
  248.     virtual ATResponse atResponse(char* buf, long ms = 30*1000);
  249.     virtual fxBool waitFor(ATResponse wanted, long ms = 30*1000);
  250.     fxBool    atCmd(const fxStr& cmd, ATResponse = AT_OK, long ms = 30*1000);
  251.     fxBool    atQuery(const char* what, u_int& v, long ms = 30*1000);
  252.     fxBool    atQuery(const char* what, fxStr& v, long ms = 30*1000);
  253.  
  254.     u_int    fromHex(const char*, int = -1);
  255.     fxStr    toHex(int, int ndigits);
  256.     fxBool    parseRange(const char*, u_int&);
  257.     fxBool    vparseRange(const char*, int nargs ...);
  258. // class 1+2 command support
  259.     fxBool    vatFaxCmd(ATResponse resp, const char* cmd ... );
  260. // modem line control
  261.     fxBool    sendBreak(fxBool pause);
  262.     fxBool    setBaudRate(BaudRate rate);
  263.     fxBool    setBaudRate(BaudRate rate, FlowControl i, FlowControl o);
  264.     fxBool    setXONXOFF(FlowControl i, FlowControl o, SetAction);
  265.     fxBool    setDTR(fxBool on);
  266.     fxBool    setInputBuffering(fxBool on);
  267.     fxBool    modemStopOutput();
  268. // server-related stuff
  269.     fxBool    getProtocolTracing();
  270.     fxBool    getHDLCTracing();
  271.     fxBool    sendSetupParams(TIFF*, Class2Params&, FaxMachineInfo&, fxStr&);
  272.     fxBool    recvCheckTSI(const fxStr&);
  273.     void    recvCSI(fxStr&);
  274.     void    recvDCS(Class2Params&);
  275.     void    recvNSF(u_int nsf);
  276.     void    recvSetupPage(TIFF* tif, long group3opts, int fillOrder);
  277.     void    recvResetPage(TIFF* tif);
  278.     fxBool    abortRequested();
  279. public:
  280.     virtual ~FaxModem();
  281.  
  282.     /*
  283.      * Modems are assumed to be configured for facsimile
  284.      * service in normal operation.  If a client wants to
  285.      * switch to voice or data service, these methods should
  286.      * be invoked.  Note that these will fail if the modem
  287.      * does not support the appropriate service.
  288.      */
  289.     virtual fxBool dataService();        // transition to data service
  290.     virtual fxBool voiceService();        // transition to voice service
  291.  
  292.     virtual fxBool sync(long ms = 0);        // synchronize (wait for "OK")
  293.     virtual fxBool reset(long ms = 5*1000);    // reset modem state
  294.     virtual fxBool abort(long ms = 5*1000);    // abort current session
  295.     virtual void hangup();            // hangup the phone
  296.  
  297. // configuration controls
  298.     virtual void setSpeakerVolume(SpeakerVolume);
  299.     virtual void setLID(const fxStr& number) = 0;
  300. // configuration query
  301.     const fxStr& getModel() const;
  302.     const fxStr& getManufacturer() const;
  303.     const fxStr& getRevision() const;
  304. // methods for querying modem capabilities
  305.     virtual fxBool supports2D() const;
  306.     virtual fxBool supportsEOLPadding() const;
  307.     virtual fxBool supportsVRes(float res) const;
  308.     virtual fxBool supportsPageWidth(u_int w) const;
  309.     virtual fxBool supportsPageLength(u_int l) const;
  310.  
  311.     virtual int selectSignallingRate(int br) const;
  312.     u_int getBestSignallingRate() const;
  313.  
  314.     u_int getBestScanlineTime() const;
  315.     virtual int selectScanlineTime(int st) const;
  316.  
  317.     u_int getBestVRes() const;
  318.     u_int getBestDataFormat() const;
  319.     u_int getBestPageWidth() const;
  320.     u_int getBestPageLength() const;
  321.     u_int modemDIS() const;
  322.  
  323.     /*
  324.      * Send protocol.  The expected sequence is:
  325.      *
  326.      * if (dial(number) == OK) {
  327.      *      sendBegin();
  328.      *      if (getPrologue() and parameters acceptable) {
  329.      *         select send parameters
  330.      *         sendSetupPhaseB();
  331.      *         for (each file)
  332.      *        if (!sendPhaseB()) break;
  333.      *      }
  334.      *      sendEnd();
  335.      * }
  336.      * hangup();
  337.      *
  338.      * The post page handling parameter to sendPhaseB enables the
  339.      * client to control whether successive files are lumped together
  340.      * as a single T.30 document or split apart.  This is important
  341.      * for doing things like keeping cover pages & documents in a
  342.      * single T.30 document.
  343.      */
  344.     virtual CallStatus dial(const char* number);
  345.     virtual void sendBegin();
  346.     virtual fxBool getPrologue(Class2Params&,
  347.     u_int& nsf, fxStr& csi, fxBool& hasDoc) = 0;
  348.     virtual void sendSetupPhaseB();
  349.     virtual fxBool sendPhaseB(TIFF*, Class2Params&, FaxMachineInfo&,
  350.     fxStr& pph, fxStr& emsg) = 0;
  351.     virtual void sendEnd();
  352.  
  353.     /*
  354.      * Receive protocol.  The expected sequence is:
  355.      *
  356.      * if (waitForRings(nrings)) {    # wait before answering phone
  357.      *    case (answerCall(type, emsg)) {
  358.      *    CALLTYPE_FAX:
  359.      *        if (recvBegin()) {
  360.      *          do {
  361.      *        TIFF* tif = TIFFOpen(..., "w");
  362.      *        int ppm = PPM_EOP;
  363.      *        do {
  364.      *            if (!recvPage(tif, ppm, emsg))
  365.      *                error during receive;
  366.      *            } while (ppm == PPM_MPS);
  367.      *        deal with received file
  368.      *          } while (ppm != PPM_EOP);
  369.      *          recvEnd();
  370.      *        }
  371.      *        hangup();
  372.      *      CALLTYPE_DATA:
  373.      *        dataService();
  374.      *        do data kinds of things...
  375.      *      CALLTYPE_VOICE:
  376.      *        voiceService();
  377.      *        do voice kinds of things...
  378.      *    }
  379.      * }
  380.      */
  381.     virtual fxBool waitForRings(u_int rings);
  382.     virtual CallType answerCall(AnswerType, fxStr& emsg);
  383.     virtual fxBool recvBegin(fxStr& emsg) = 0;
  384.     virtual fxBool recvPage(TIFF*, int& ppm, fxStr& em) = 0;
  385.     virtual fxBool recvEnd(fxStr& emsg) = 0;
  386.  
  387.     /*
  388.      * Polling protocol (for polling a remote site).  This is done
  389.      * in conjunction with a send operation: first, before dialing,
  390.      * call requestToPoll(), then after sending any files, do:
  391.      *
  392.      * if (pollBegin(...)) {
  393.      *    do {
  394.      *        TIFF* tif = TIFFOpen(..., "w");
  395.      *        if (recvPhaseB(tif, ..., ppm, ...) deal with received file
  396.      *      } while (ppm != PPM_EOP);
  397.      *      recvEnd();
  398.      * }
  399.      *
  400.      * (i.e. it's just like a receive operation.)
  401.      */
  402.     virtual fxBool requestToPoll() = 0;
  403.     virtual fxBool pollBegin(const fxStr& pollID, fxStr& emsg) = 0;
  404. };
  405. inline long FaxModem::getDataTimeout() const        { return dataTimeout; }
  406. inline const fxStr& FaxModem::getModel() const        { return modemModel; }
  407. inline const fxStr& FaxModem::getManufacturer() const    { return modemMfr; }
  408. inline const fxStr& FaxModem::getRevision() const    { return modemRevision; }
  409.  
  410. #define streq(a, b)    (strcmp(a,b) == 0)
  411. #define    strneq(a, b, n)    (strncmp(a,b,n) == 0)
  412. #endif /* _FAXMODEM_ */
  413.